package com.universe.arithmetic.search;

/**
 * @Author：ghostbamboo
 * @Description： 插值查找
 * @Theory： 插值查找算法类似于二分查找，不同的是插值查找每次从自适应 mid 处开始查找。
 * int mid = low + (high - low) * (key - arr[low]) / (arr[high] - arr[low]) ;
 * 对应前面的代码公式：
 * int mid = left + (right – left) * (findVal – arr[left]) / (arr[right] – arr[left])
 * 1) 对于数据量较大，关键字分布比较均匀的查找表来说，采用插值查找, 速度较快.
 * 2) 关键字分布不均匀的情况下，该方法不一定比折半查找要好
 * @Date： 14:01 2020/1/6
 */
public class InsertValueSearch {
    public static int count = 0;


    public static int insertValueSearch(int left, int right, int[] arr, int value) {
        count++;
        //避免计算出来的mid越界
        if (left > right || value < arr[0] || value > arr[arr.length - 1]) {
            return -1;
        }
        //求出自适应中值
        int mid = left + (right - left) * (value - arr[left]) / (arr[right] - arr[left]);
        if (arr[mid] > value) {
            //向左递归
            return insertValueSearch(left, mid, arr, value);
        } else if (arr[mid] < value) {
            //向右递归
            return insertValueSearch(mid + 1, right, arr, value);
        } else {
            return mid;
        }
    }

    public static void main(String[] args) {
        int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
        int value = 20;
        int res = insertValueSearch(0, arr.length - 1, arr, value);
        if (res != -1) {
            System.out.printf("找到 %d 对应的下标为 %d ", value, res);
        } else {
            System.out.println(value + " 没有找到");
        }

        System.out.println("执行查找次数为:" + count);

    }

}
